if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING INTERNAL)
endif(NOT CMAKE_BUILD_TYPE)

project(CGM)
cmake_minimum_required(VERSION 3.1)
SET(PACKAGE_NAME "CGM")
SET(PACKAGE_VERSION "16.0.1")

list(INSERT CMAKE_MODULE_PATH 0
  "${CMAKE_CURRENT_SOURCE_DIR}/config")

include(GNUInstallDirs)

#Add our Cmake directory to the module search path
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/config ${CMAKE_MODULE_PATH})
################################################################################
# Set up version info
################################################################################
include (config/GetAcInitVersion.cmake)
get_ac_init_version()
set ( CGM_VERSION_STRING "${PACKAGE_NAME} ${VERSION_STRING}" )
set ( CGM_VERSION        "${VERSION_STRING}" )
set ( CGM_MAJOR_VERSION  ${MAJOR_VERSION}  )
set ( CGM_MINOR_VERSION  ${MINOR_VERSION}  )
if ( DEFINED PATCH_VERSION )
  set ( CGM_VERSION_PATCH "${PATCH_VERSION}" )
else ( DEFINED PATCH_VERSION )
  if ( CGM_MINOR_VERSION EQUAL 99 )
    set ( CGM_VERSION_STRING "${CGM_VERSION_STRING} (alpha)" )
  else ( CGM_MINOR_VERSION EQUAL 99 )
    set ( CGM_VERSION_STRING "${CGM_VERSION_STRING} (beta)" )
  endif ( CGM_MINOR_VERSION EQUAL 99 )
endif ( DEFINED PATCH_VERSION )

IF(CMAKE_VERSION VERSION_EQUAL "3.0.0" OR CMAKE_VERSION VERSION_GREATER "3.0.0")
  cmake_policy(SET CMP0003 NEW)
  cmake_policy(SET CMP0020 NEW)
  cmake_policy(SET CMP0042 OLD)
ENDIF ()

set ( abs_srcdir   ${CMAKE_SOURCE_DIR} )
set ( abs_builddir ${PROJECT_BINARY_DIR} )

include(CGMMacros)

# Choose static or shared libraries:
option(BUILD_SHARED_LIBS "Build CGMA with shared libraries." ON)
option(ENABLE_MPI        "Should CGM be compiled with MPI support?"       OFF )
option(ENABLE_OCC        "Build CGM with OpenCascade geometry kernel" OFF)
option(ENABLE_TESTING   "Enable Testing"                                  ON  )

include (config/CheckCompilerFlags.cmake)

# check for MPI package
set( MPI_FOUND OFF )
set( CGM_HAVE_MPI OFF )
set (CGM_HAVE_MPI OFF CACHE INTERNAL "Found necessary MPI components. Configure CGM with it." )
if ( ENABLE_MPI )
  find_package( MPI REQUIRED )
  # CMake FindMPI script is sorely lacking:
  if ( MPI_LIBRARY AND MPI_INCLUDE_PATH )
    set( MPI_FOUND ON )
  endif ( MPI_LIBRARY AND MPI_INCLUDE_PATH )

  if ( MPI_FOUND )
    set(CGM_DEFINES "${CGM_DEFINES} -DUSE_MPI" )
    set(CMAKE_CXX_COMPILE_FLAGS "${CMAKE_CXX_COMPILE_FLAGS} ${MPI_COMPILE_FLAGS}")
    set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} ${MPI_LINK_FLAGS}")
    include_directories(${MPI_INCLUDE_PATH})
    set( CGM_HAVE_MPI ON )
  endif ( MPI_FOUND )
endif ( ENABLE_MPI )

set(PRIMARY_GEOMETRY_ENGINE "FACETS")
set(CGM_HAVE_OCC OFF )
if (ENABLE_OCC)
  set(OCC_DIR   ""  CACHE PATH  "Build CGM with OpenCascade geometry kernel")
  execute_process(COMMAND ${CMAKE_SOURCE_DIR}/config/LocateConfigFile.sh OCEConfig.cmake 
                          ${OCC_DIR}/lib/oce-*
                          ${OCC_DIR}/lib/cmake/oce-* 
                          ${OCC_DIR}/OCE.framework/Versions/*/Resources 
                          ${OCC_DIR}/lib/x86_64-linux-gnu/oce-*
                  TIMEOUT 2
                  RESULT_VARIABLE FINDSUCCESS
                  OUTPUT_VARIABLE OCECONFIG_FILE_PATH
                  ERROR_VARIABLE  FINDERR
                  ERROR_QUIET
                  OUTPUT_STRIP_TRAILING_WHITESPACE
                  )
# message("RES: ${FINDSUCCESS}, ERR: ${ERROR_VARIABLE}, OUTPUT=${OCECONFIG_FILE_PATH}")
  get_filename_component(OCE_DIR "${OCECONFIG_FILE_PATH}" PATH)
  message("-- OCE_DIR: ${OCC_DIR}, and OCEConfig.cmake location = ${OCECONFIG_FILE_PATH}")
  if (IS_DIRECTORY ${OCE_DIR})
    find_package(OCE CONFIG)
  endif(IS_DIRECTORY ${OCE_DIR})
  if(OCE_FOUND)
      message(STATUS "Found OCE version ${OCE_VERSION}")
      # Include files reside in ${OCE_INCLUDE_DIRS};
      include_directories(${OCE_INCLUDE_DIRS})
      # We do not need library path, they will be automatically imported.
      set(OPENCASCADE_DIR ${OCE_DIR})
  else(OCE_FOUND)
      # OCE not found; either it is not found and user
      # has to set OCE_DIR to the directory containing
      # OCEConfig.cmake, or OCE is not installed and we
      # try to find OpenCascade files.
      if(DEFINED ENV{CASROOT})
          if(NOT DEFINED OCC_INCLUDE_PATH)
              set(OCC_INCLUDE_PATH "$ENV{CASROOT}/inc")
          endif(NOT DEFINED OCC_INCLUDE_PATH)
          if(NOT DEFINED OCC_LIB_PATH)
              if(WIN32)
                  set(OCC_LIB_PATH "$ENV{CASROOT}/win32/lib")
              else(WIN32)
                  if(APPLE)
                      set(OCC_LIB_PATH "/Library/OpenCASCADE/6.3.0/lib")
                  else(APPLE)
                      set(OCC_LIB_PATH "$ENV{CASROOT}/lin/lib")
                  endif(APPLE)
              endif(WIN32)
          endif(NOT DEFINED OCC_LIB_PATH)
      else(DEFINED ENV{CASROOT})
          if(NOT DEFINED OCC_INCLUDE_PATH OR NOT DEFINED OCC_LIB_PATH)
              message(WARNING "To specify paths of OpenCascade files, you may either define the CASROOT environment variable, or set both OCC_INCLUDE_PATH and OCC_LIB_PATH variables.")
          endif(NOT DEFINED OCC_INCLUDE_PATH OR NOT DEFINED OCC_LIB_PATH)
      endif(DEFINED ENV{CASROOT})
      if(DEFINED OCC_INCLUDE_PATH)
          message(STATUS "OCC search path for include files: OCC_INCLUDE_PATH=${OCC_INCLUDE_PATH}")
          include_directories(${OCC_INCLUDE_PATH})
      endif(DEFINED OCC_INCLUDE_PATH)
      if(DEFINED OCC_LIB_PATH)
          message(STATUS "OCC search path for libraries: OCC_LIB_PATH=${OCC_LIB_PATH}")
          link_directories(${OCC_LIB_PATH})
      endif(DEFINED OCC_LIB_PATH)
      find_package(OpenCasCade CONFIG REQUIRED)
      set(OPENCASCADE_DIR ${OCC_DIR})
  endif(OCE_FOUND)

  if ( OCC_FOUND OR OCE_FOUND )
    set(CGMA_OCC_DEFINES "-DHAVE_OCC")
    set(PRIMARY_GEOMETRY_ENGINE "OCC")

    if ( OCC_FOUND )
      set(ISOCE "FALSE")
      set(OpenCascade_DIR ${OCC_DIR})
      set(OpenCascade_VERSION ${OCC_VERSION_STRING})
      set(OpenCascade_LIBRARIES ${OCC_LIBRARIES})
      set(OpenCascade_INCLUDES  ${OCC_INCLUDE_PATH}) #OCC_INCLUDE_DIR
    else ( OCC_FOUND )
      #get_filename_component(OCE_LIBRARY_DIR "${OCE_DIR}/OCEConfig.cmake" PATH)
      set(ISOCE "TRUE")
      set(OpenCascade_DIR ${OCE_DIR})
      set(OpenCascade_VERSION ${OCE_VERSION})
      set(OpenCascade_LIBRARIES ${OCE_LIBRARIES})
      set(OpenCascade_INCLUDES  ${OCE_INCLUDE_DIRS})
    endif ( OCC_FOUND )

    set(HAVE_STEP 0)
    set(HAVE_STL 0)
    set(HAVE_IGES 0)
    foreach(libitem ${OpenCascade_LIBRARIES})
      STRING(FIND ${libitem} "libTKSTEP" libTKSTEPPos )
      if (${libTKSTEPPos} LESS 0 AND ${HAVE_STEP} EQUAL 0)
        set(CGMA_OCC_DEFINES "${CGMA_OCC_DEFINES} -DHAVE_OCC_STEP")
        set(HAVE_STEP 1)
      endif (${libTKSTEPPos} LESS 0 AND ${HAVE_STEP} EQUAL 0)
      STRING(FIND ${libitem} "libTKSTL" libTKSTLPos )
      if (${libTKSTLPos} LESS 0 AND ${HAVE_STL} EQUAL 0)
        set(CGMA_OCC_DEFINES "${CGMA_OCC_DEFINES} -DHAVE_OCC_STL")
        set(HAVE_STL 1)
      endif (${libTKSTLPos} LESS 0 AND ${HAVE_STL} EQUAL 0)
      STRING(FIND ${libitem} "libTKIGES" libTKIGESPos )
      if (${libTKIGESPos} LESS 0 AND ${HAVE_IGES} EQUAL 0)
        set(CGMA_OCC_DEFINES "${CGMA_OCC_DEFINES} -DHAVE_OCC_IGES")
        set(HAVE_IGES 1)
      endif (${libTKIGESPos} LESS 0 AND ${HAVE_IGES} EQUAL 0)
    endforeach(libitem ${OpenCascade_LIBRARIES})

    set(CGM_HAVE_OCC ON )
    set(CGMA_OCC_DEFINES "${CGMA_OCC_DEFINES} -DOCCGEOMETRY -D_OCC64")
    set_property(GLOBAL APPEND
      PROPERTY CGM_DEFINES
      ${CGMA_OCC_DEFINES})

    include_directories(${OpenCascade_INCLUDES})
    mark_as_advanced(OpenCascade_LIBRARIES OpenCascade_INCLUDES OpenCascade_DIR OpenCascade_VERSION)
  endif ( OCC_FOUND OR OCE_FOUND )
endif (ENABLE_OCC)

if (WIN32)
  set(cmakedir cmake)
else ()
  set(cmakedir lib/cmake/CGM)
endif ()
set_property(GLOBAL
  PROPERTY CMAKE_LIB_DIR ${cmakedir})

# Add some standard libraries for linkage
find_library(M m)

### Add the subdirectories for sources
add_subdirectory(itaps)
add_subdirectory(src/geom)
add_subdirectory(src/init)
add_subdirectory(src/util)

set(export_sym "")
if (WIN32)
  set(export_sym "__declspec(dllexport) ")
endif ()

# VSM: Unclear why the following cgm_dummy function is defined. This doesn't make sense
# Is this to support Windows or just to test configuration on it. If it's the latter, it 
# should be removed after creation.
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cgm_export_symbol.cpp" "${export_sym}int cgm_dummy() { return 0; }\n")
add_library(cgm "${CMAKE_CURRENT_BINARY_DIR}/cgm_export_symbol.cpp")
target_link_libraries(cgm
  PUBLIC
    cgm_init
    cgm_geom
    cgm_util
    ${CMAKE_DL_LIBS} ${M}
)

################################################################################
# Testing Related Settings
################################################################################
#turn on ctest if we want testing
if ( ENABLE_TESTING )
  enable_testing()
  add_subdirectory( test )
endif()

CONFIGURE_FILE(config/CGMConfig.cmake.h.in "${PROJECT_BINARY_DIR}/src/cgm/CGMConfig.h" @ONLY)
install(TARGETS cgm
  EXPORT    cgm
  RUNTIME   DESTINATION bin
  LIBRARY   DESTINATION lib
  ARCHIVE   DESTINATION lib
  COMPONENT Runtime)

get_property(cgm_exports GLOBAL
  PROPERTY cgm_export_targets)
export(
  TARGETS ${cgm_exports} cgm
  FILE    "${CGM_BINARY_DIR}/CGMTargets.cmake")

get_property(cgm_libraries GLOBAL
    PROPERTY cgm_libs)

#include (ResolveCompilerPaths)
#RESOLVE_LIBRARIES(CGM_LIBRARIES "${cgm_libraries}")
set(CGM_LIBRARIES ${cgm_libraries})

install(
  EXPORT      cgm
  DESTINATION "${cmakedir}"
  FILE        CGMTargets.cmake
  COMPONENT   Development)

# Install top-level headers:
install(
  FILES
  ${CGM_BINARY_DIR}/src/cgm/CGMConfig.h
  DESTINATION include/cgm
  COMPONENT Development
)

configure_file(
  "${CGM_SOURCE_DIR}/config/CGMConfig.cmake.cmake"
  "${CGM_BINARY_DIR}/CGMConfig.cmake"
  @ONLY)
install(
  FILES       "${CGM_BINARY_DIR}/CGMConfig.cmake"
              "${CGM_SOURCE_DIR}/config/CGMMacros.cmake"
  DESTINATION "${cmakedir}"
  COMPONENT   Development)

# CMake does not define uninstall target. Look at install manifest and remove
# all the files recursively.
CONFIGURE_FILE(
    "${CMAKE_CURRENT_SOURCE_DIR}/config/cmake_uninstall.cmake.in"
    "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
    IMMEDIATE @ONLY
    )

configure_file(
  "${CGM_SOURCE_DIR}/test/TestConfig.h.in"
  "${CGM_BINARY_DIR}/test/TestConfig.h"
  @ONLY)

message("
------------------------------------------------------------------------
  ${PROJECT_NAME} ${PACKAGE_VERSION}:  Configuration successful.

  Build type: ${CMAKE_BUILD_TYPE}
  Flags: ${CXXFLAGS}

  Enabled functionality:

    OCC: ............... ${ENABLE_OCC}
    MPI: ............... ${ENABLE_MPI}

  Installation directory: ${CMAKE_INSTALL_PREFIX}
  
  To build, type \"make\".\n")

